﻿using System;
using System.Collections.Generic;
using System.Linq;
using Common.GSMLibrary;
using System.Threading;
using NTTDATA.BEENChina.CaseMonitor.DAO;

namespace NTTDATA.BEENChina.CaseMonitor.Notice
{
    public class Mobile
    {   
        private GSMModem modem = null;
        private static object lockobj = new object();
        private DateTime callTime = DateTime.MaxValue;

        public Mobile(string port, int baudRate)
        {
            this.ComPort = port;
            this.BaudRate = baudRate;
            modem = new GSMModem(this.ComPort, this.BaudRate);
        }

        private List<string> MobileNumbers
        {
            get;
            set;
        }

        private string Message
        {
            get;
            set;
        }

        private string ComPort
        {
            get;
            set;
        }

        private int BaudRate
        {
            get;
            set;
        }

        public void Notice(List<string> numbers,string msg)
        {
            if (numbers == null || numbers.Count == 0)
            {
                throw new Exception("Have no phone numbers!");
            }

            this.MobileNumbers = numbers;
            this.Message = msg;

            Thread thread = new Thread(new ThreadStart(this.ThreadFun));
            thread.Start();


        }

        private void ThreadFun()
        {
            lock (lockobj)
            {
                try
                {
                    modem.OpenComm();

                    while (true)
                    {
                        foreach (string number in MobileNumbers)
                        {
                            if (String.IsNullOrEmpty(number.Trim()) ||
                                string.IsNullOrWhiteSpace(number.Trim()) )
                            {
                                //电话号码是空白
                                continue;
                            }

                            try
                            {
                                SendMessage(number);

                                CaseDBAccesser.InsertProcessLog("send message", number, this.Message);
                            }
                            catch (Exception ex )
                            {
                                Log.Console.Error(string.Format("Mobile.ThreadFun() Send Msg {0} ,{1} error",number,Message), ex);
                                
                            }

                            System.Threading.Thread.Sleep(10000);

                            try
                            {
                                modem.Call(number);
                                CaseDBAccesser.InsertProcessLog("call", number, string.Empty);
                            }
                            catch (Exception ex)
                            {
                                Log.Console.Error(string.Format("Mobile.ThreadFun() Call Tel {0} error", number), ex);
                                
                            }
                          

                            callTime = DateTime.Now;

                            try
                            {
 
                                if (ReceiveMsg(number))
                                {
                                    CaseDBAccesser.InsertProcessLog("ReceiveMsg", number, string.Empty);
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Console.Error(string.Format("Mobile.ThreadFun() Receive Msg {0} error", number), ex);

                            }
                           
                        }
                    }
                }
                catch(Exception ex)
                {
                    Log.Console.Error("Notice.mobile ThreadFun()", ex);
                }
                finally
                {
                    modem.CloseComm();
                }
            }
        }

        private void SendMessage(string number)
        {
            int result;
            int sendLength = 70;

            int count = Math.DivRem(this.Message.Length, sendLength, out result);

            if (result > 0)
                count += 1;

            int starPos = 0;

            for (int i = 0; i < count; i++)
            {
                string msg = string.Empty;

                if ( (starPos +  sendLength) > this.Message.Length)
                {
                    msg = Message.Substring(starPos);
                }
                else
                {
                    msg = Message.Substring(starPos, sendLength);   
                }

                
                modem.SendMsg(number, msg);
                
                System.Threading.Thread.Sleep(5000);

                starPos += sendLength;

                Log.Console.Debug(  string.Format("send message {0}:{1}", number, msg));
            }
            
        }

        private bool ReceiveMsg(string number)
        {
            if (number == null)
            {
                return false;
            }

            for(int i=0;i<180;i++)
            {
                String[] msg = modem.GetUnReadMsg();
                if(msg==null || msg.All(string.IsNullOrEmpty))
                {
                    System.Threading.Thread.Sleep(1000);
                }
                else
                {
                    if (ContainMsg(msg,number))
                    {
                        return true;
                    }
                }
            }
            return false ;
        }

        private bool ContainMsg(string[] allMsg,string number)
        {
            if (allMsg == null || number ==null || number ==string.Empty )
            {
                return false;
            }

            foreach (String msg in allMsg)
            {
                if (msg == null)
                {
                    continue;
                }

                string[] msgData = msg.Split(new char[] { ',' });
                if(msgData.Length <4)
                {
                    throw new Exception ("Message format error!");
                }

                DateTime receiveTime = DateTime.ParseExact(msgData[2].Substring(0, 14), "yyyyMMddHHmmss", System.Globalization.CultureInfo.InvariantCulture);
                if (msgData[1].Contains(number) && callTime.CompareTo(receiveTime)<0 )
                {
                    //save msg to log
                    CaseDBAccesser.InsertProcessLog("receive message", number,  msg);

                    return true;
                }
            }
            return false;
        }
    }
}